/*
 *  Copyright 2010 Mahbub Mozadded Sowrov.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

/*
 * ParseProjectActivity.java
 * Date: Oct 10, 2010
 * Version: 1.0
 */
package com.sowrov.afrigis.tools.timesheet.parse.javascript;

import com.sowrov.afrigis.tools.timesheet.Activity;
import com.sowrov.afrigis.tools.timesheet.Project;
import java.util.ArrayList;
import org.mozilla.javascript.CompilerEnvirons;
import org.mozilla.javascript.ErrorReporter;
import org.mozilla.javascript.FunctionNode;
import org.mozilla.javascript.Parser;
import org.mozilla.javascript.ScriptOrFnNode;
import org.mozilla.javascript.Token;
//import org.w3c.dom.NodeList;
//import org.w3c.dom.html2.HTMLDocument;
//import org.xml.sax.SAXException;
//import java.io.File;
//import java.io.IOException;
//import org.lobobrowser.html.parser.DocumentBuilderImpl;
//import org.lobobrowser.html.test.SimpleUserAgentContext;

/**
 * <p>Instance of <code>JavascriptParser</code> is thread safe.</p>
 *
 * @author sowrov
 */
public class JavascriptParser {

    private String rawJs = "";
    private ArrayList<Project> projects;
    private CompilerEnvirons compilerEnv;
    private ErrorReporter errorReporter;
    private Parser parser;
    private ScriptOrFnNode scriptOrFnNode;

    public JavascriptParser(){
        this.projects = new ArrayList<Project>();
        this.compilerEnv = new CompilerEnvirons();
        this.errorReporter = this.compilerEnv.getErrorReporter();
        this.parser = new Parser(compilerEnv, errorReporter);
    }
    
    public JavascriptParser(String rawJs) {
        this.projects = new ArrayList<Project>();
        this.compilerEnv = new CompilerEnvirons();
        this.errorReporter = this.compilerEnv.getErrorReporter();
        this.parser = new Parser(compilerEnv, errorReporter);
        this.setJs(rawJs);
    }

    public void setJs(String rawJs) {
        this.rawJs = rawJs;
        this.parseJS();
    }

    public ArrayList<Project> getProjects(){
        return this.projects;
    }

    private void parseJS() {
        this.scriptOrFnNode = this.parser.parse(this.rawJs, "", 1);
        //System.out.println(scriptOrFnNode.getFunctionCount());
        FunctionNode functionNode = scriptOrFnNode.getFunctionNode(12); //showlinks

        org.mozilla.javascript.Node funNode = functionNode.getFirstChild().getFirstChild();
        org.mozilla.javascript.Node blockNode = null, conditionNode = null, itemNode = null;

        int argCount = 0;
        Project p = null;
        while (funNode != null) {
            if (funNode.getType() == Token.BLOCK) {
//                System.out.println("Found Block");
                blockNode = funNode.getFirstChild();

                while (blockNode != null) {
                    if (blockNode.getType() == Token.IFNE) {
                        if (p!=null) {
                            this.projects.add(p);
                        }
//                        System.out.println("If ont eq");
                        if (blockNode.getFirstChild().getType() == Token.EQ) {
                            p = new Project();
                            conditionNode = blockNode.getFirstChild().getFirstChild(); //selection
                            //System.out.println("Name: " + conditionNode.getString());
                            conditionNode = conditionNode.getNext(); //id
                            p.setId(conditionNode.getString());
//                            System.out.println("Id: " + conditionNode.getString());
                        }
                    } else if (blockNode.getType() == Token.BLOCK) {
//                        System.out.println("Block");
                        conditionNode = blockNode.getFirstChild();
                        while (conditionNode != null) {
                            if (conditionNode.getFirstChild().getType() == Token.CALL) {
                                Activity activity = new Activity();
                                itemNode = conditionNode.getFirstChild().getFirstChild(); //opt
                                //System.out.println("  op:" + itemNode.getString());

                                itemNode = itemNode.getNext();
//                                System.out.println("  actid:" + itemNode.getString());
                                if (!itemNode.getString().equals("dummy")) {
                                    activity.setId(itemNode.getString());

                                    itemNode = itemNode.getNext();
                                    //System.out.println("  style:" + itemNode.getString());//ignore

                                    itemNode = itemNode.getNext();
    //                                System.out.println("  name:" + itemNode.getString());
                                    activity.setName(itemNode.getString());
                                    if (p != null) {
                                        p.addActivity(activity);
                                    }
                                }
                            }
                            conditionNode = conditionNode.getNext();
                        }
                    }
                    blockNode = blockNode.getNext();
                }
//                    String str = funNode.toStringTree(scriptOrFnNode);
//                    System.out.println(str);
            }
            funNode = funNode.getNext();
            argCount++;
        }
        //System.out.println(argCount);
    }

//    public static void main(String[] arg) throws SAXException, IOException {
//        SimpleUserAgentContext context;
//        DocumentBuilderImpl docBuilder;
//        context = new SimpleUserAgentContext();
//        context.setAppName("Mozilla Firefox");
//        context.setAppCodeName("Mozilla");
//        context.setScriptingEnabled(false);
//        context.setExternalCSSEnabled(false);
//
//        docBuilder = new DocumentBuilderImpl(context);
//        String uri = "f:/dev/java/TimeSheetManager/test_input/ActivitySubmitPage0.htm";
//
//        HTMLDocument document = (HTMLDocument) docBuilder.parse(new File(uri));
//        NodeList nlist = document.getElementsByTagName("script");
//        org.w3c.dom.Node node = nlist.item(0);
//        ParseProjectActivity ppa = new ParseProjectActivity(node.getTextContent());
//        System.out.println("-------------");
//        ArrayList<Project> projects = ppa.getProjects();
//        for (int i=0; i<projects.size(); i++) {
//            System.out.println("Project Id: "+projects.get(i).getId());
//            int activityCount = projects.get(i).getActivityCount();
//            for (int j=0; j<activityCount; j++) {
//                Activity act = projects.get(i).getActivityAt(j);
//                System.out.println("  Ac Name:"+act.getName()+" AcId:"+act.getId());
//            }
//        }
//    }

//    output
//    Project Id: 560
//  Ac Name:--- General AcId:dummy
//  Ac Name:Annual Leave AcId:95
//  Ac Name:HR  AcId:98
//  Ac Name:Office Meetings & Socials AcId:103
//  Ac Name:Performance Discussion AcId:137
//  Ac Name:Public Holiday AcId:144
//  Ac Name:Research AcId:99
//  Ac Name:Sick Leave AcId:100
//  Ac Name:Special Leave AcId:101
//  Ac Name:Training (internal by AfriGIS) AcId:106
//Project Id: 1049
//  Ac Name:--- Development AcId:dummy
//  Ac Name:Bug Fixing AcId:43
//  Ac Name:Code Reviews AcId:45
//  Ac Name:Coding AcId:46
//  Ac Name:Database Design AcId:47
//  Ac Name:Database Maintenance AcId:49
//  Ac Name:Design AcId:51
//  Ac Name:Documentation AcId:52
//  Ac Name:--- Functional Specialist AcId:dummy
//  Ac Name:Functional Requirements AcId:59
//  Ac Name:Functional Spec Review AcId:60
//  Ac Name:Functional Specification  AcId:61
//  Ac Name:--- IT Support AcId:dummy
//  Ac Name:IT Support AcId:142
//  Ac Name:--- Project Management AcId:dummy
//  Ac Name:Project Communication AcId:69
//  Ac Name:Project Documentation AcId:64
//  Ac Name:Project Meeting AcId:136
//  Ac Name:Project Resource Management AcId:65
//  Ac Name:Project Time Management AcId:67
//  Ac Name:--- Quality Assurance AcId:dummy
//  Ac Name:Developer Testing AcId:77
//  Ac Name:Installation Testing AcId:75
//  Ac Name:Test Plans AcId:79
//  Ac Name:Testing AcId:78
//  Ac Name:--- Technical Support AcId:dummy
//  Ac Name:e-mail Support AcId:85
//  Ac Name:Manuals AcId:81
//Project Id: 1170
//  Ac Name:--- General AcId:dummy
//  Ac Name:Breakfast AcId:1114
//  Ac Name:Dinner AcId:1116
//  Ac Name:Lunch AcId:1115
//Project Id: 1171
//  Ac Name:--- General AcId:dummy
//  Ac Name:Recreation AcId:1117
//Project Id: 1175
//  Ac Name:--- In Lieu Holiday AcId:dummy
//  Ac Name:Public holiday exchange AcId:1119
//  Ac Name:Weekend exchange AcId:1118
//Project Id: 1184
//  Ac Name:--- No Work AcId:dummy
//  Ac Name:No Work AcId:1120
//  Ac Name:Contact your Proj. Manager. AcId:dummy
}
